<template>
  <el-dialog :title="config.title" v-model="dialogVisible" :width="width" align-center>
    <!-- 头部插槽 -->
    <slot name="header"></slot>
    <div class="flex justify-between mt-3">
      <!-- 左边可选区域 -->
      <div class="w-[48%] border border-gray-300 rounded-lg flex flex-col h-[560px] relative">
        <div
          class="flex justify-between h-10 px-4 py-2 bg-gray-100 rounded-t-lg text-base font-medium leading-6 flex-shrink-0">
          <span>{{ $t('trackMgr.optional') }}</span>
          <span>{{ optionalList.length }} {{ $t('trackMgr.items') }}</span>
        </div>
        <div class="flex-1 flex flex-col p-4 overflow-hidden">
          <div class="flex-shrink-0 mb-2.5">
            <el-input v-model="optionalSearch" :placeholder="config.searchPlaceholder" clearable class="w-full"
              :suffix-icon="Search" />
          </div>
          <div class="flex-1 flex flex-col min-h-0">
            <div v-if="filteredOptionalList.length > 0" class="min-h-[400px] flex-1">
              <el-table max-height="400" v-loading="optionalLoading || optionalSearchLoading || props.dataLoading" :data="paginatedOptionalList" style="width: 100%;"
                @selection-change="handleOptionalSelectionChange">
                <el-table-column type="selection" width="55" />
                <el-table-column v-for="column in config.columns" :key="column.prop" :prop="column.prop"
                  :label="column.label" :min-width="column.minWidth || '50px'" :align="column.align || 'left'"
                  showOverflowTooltip>
                  <template v-if="column.render" #default="{ row }">
                    <div v-if="column.prop === 'roles'">
                      <component :is="column.render(row, 'left')" />
                    </div>
                    <component v-else :is="column.render(row)" />
                  </template>
                </el-table-column>
              </el-table>
            </div>
            <div v-else
              class="no-data-wrapper flex-1 flex justify-center items-center flex-col border-b border-gray-300">
              <img :src="noDataImage" alt="" class="mb-4 w-[100px] h-[100px]">
              <span class="text-gray-400 text-sm font-normal leading-6 text-center">
                {{ config.type === 'judge' && !props.role
                  ? $t('trackMgr.noDataSelectRole')
                  : config.type === 'judge' && props.role
                    ? $t('该角色下无数据，请重新选择')
                    : $t('trackMgr.noData') }}
              </span>
            </div>
          </div>
          <div class="flex-shrink-0 flex justify-end mt-3 h-8 items-center">
            <el-pagination size="small" layout="prev, pager, next" :total="filteredOptionalList.length"
              :page-size="pageSize" v-model:current-page="optionalCurrentPage"
              @current-change="handleOptionalPageChange" />
          </div>
        </div>
      </div>
      <!-- 中间操作按钮 -->
      <div class="operate-btns flex flex-col justify-center items-center gap-2.5 mx-4 my-auto">
        <el-button :icon="ChevronRight" type="primary" @click="moveToSelected"
          :disabled="selectedOptional.length === 0">
        </el-button>
        <el-button :icon="ChevronLeft" type="primary" @click="moveToOptional" :disabled="selectedSelected.length === 0">
        </el-button>
      </div>
      <!-- 右边已选区域 -->
      <div class="w-[48%] border border-gray-300 rounded-lg flex flex-col h-[560px]">
        <div
          class="flex justify-between h-10 px-4 py-2 bg-gray-100 rounded-t-lg text-base font-medium leading-6 flex-shrink-0">
          <span>{{ $t('trackMgr.selected') }}</span>
          <span>{{ selectedList.length }} {{ $t('trackMgr.items') }}</span>
        </div>
        <div class="flex-1 flex flex-col p-4 overflow-hidden">
          <div class="flex-shrink-0 mb-2.5">
            <el-input v-model="selectedSearch" :placeholder="config.searchPlaceholder" clearable class="w-full"
              :suffix-icon="Search" />
          </div>
          <div class="flex-1 flex flex-col min-h-0">
            <div v-if="filteredSelectedList.length > 0" class="min-h-[400px] flex-1">
              <el-table max-height="400" v-loading="selectedSearchLoading" :data="paginatedSelectedList" style="width: 100%;"
                @selection-change="handleSelectedSelectionChange">
                <el-table-column type="selection" width="55" />
                <el-table-column v-for="column in config.columns" :key="column.prop" :prop="column.prop"
                  :label="column.label" :min-width="column.minWidth || '50px'" :align="column.align || 'left'"
                  showOverflowTooltip>
                  <template v-if="column.render" #default="{ row }">
                    <component :is="column.render(row)" />
                  </template>
                </el-table-column>
              </el-table>
            </div>
            <div v-else class="min-h-[400px] flex-1 flex justify-center items-center flex-col border-b border-gray-300">
              <img :src="noDataImage" alt="" class="mb-4 w-[100px] h-[100px]">
              <span class="text-gray-400 text-sm font-normal leading-6 text-center">
                {{ $t('trackMgr.noDataSelectFromLeft') }}
              </span>
            </div>
          </div>
          <div class="flex-shrink-0 flex justify-end mt-3 h-8 items-center">
            <el-pagination size="small" layout="prev, pager, next" :total="filteredSelectedList.length"
              :page-size="pageSize" v-model:current-page="selectedCurrentPage"
              @current-change="handleSelectedPageChange" />
          </div>
        </div>
      </div>
    </div>
    <template #footer>
      <el-button @click="handleCancel">{{ $t('common.cancelTxt') }}</el-button>
      <el-button type="primary" @click="handleConfirm" :loading="props.confirmLoading"
        :disabled="!selectedList.length">{{ $t('trackMgr.confirm') }}</el-button>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, computed, watch, onUnmounted, h } from 'vue'
import { ElDialog, ElInput, ElTable, ElTableColumn, ElPagination, ElButton } from 'element-plus'
import { $t } from '@vben/locales'
import { Search } from '@vben/icons';
import noDataImage from '#/assets/images/no-data.png';
import { ChevronLeft, ChevronRight } from '@vben/icons'
// 通用数据项接口
interface SelectionItem {
  id: number | string
  [key: string]: any
}

// 列配置接口
interface ColumnConfig {
  prop: string
  label: string
  minWidth?: string
  align?: string
  tooltip?: string
  render?: (row: any, type?: any) => string | ReturnType<typeof h>
}

// 组件配置接口
interface SelectionConfig {
  title: string
  searchPlaceholder: string
  columns: ColumnConfig[]
  type: 'judge' | 'dimension' // 用于区分评委和评审维度
}

// Props 定义
interface Props {
  modelValue: boolean
  config: SelectionConfig
  confirmLoading: boolean
  optionalData?: SelectionItem[]
  selectedData?: SelectionItem[]
  width?: string
  role?: string
  dataLoading?: boolean // 外部数据加载状态
}

const props = withDefaults(defineProps<Props>(), {
  optionalData: () => [],
  selectedData: () => [],
  width: '904px',
  dataLoading: false
})

// Emits 定义
const emit = defineEmits<{
  'update:modelValue': [value: boolean]
  'confirm': [selectedItems: SelectionItem[]]
  'cancel': []
  'selectedListChange': [selectedItems: SelectionItem[]]
}>()

// 响应式数据
const dialogVisible = computed({
  get: () => props.modelValue,
  set: (value) => emit('update:modelValue', value)
})

// 可选区域相关
const optionalList = ref<SelectionItem[]>([])
const optionalLoading = ref(false)
const optionalSearch = ref('')
const optionalSearchLoading = ref(false) // 搜索loading状态
const optionalCurrentPage = ref(1)
const pageSize = ref(10)
const selectedOptional = ref<SelectionItem[]>([])

// 已选区域相关
const selectedList = ref<SelectionItem[]>([])
const selectedSearch = ref('')
const selectedSearchLoading = ref(false) // 搜索loading状态
const selectedCurrentPage = ref(1)
const selectedSelected = ref<SelectionItem[]>([])
const isInitializing = ref(false) // 添加初始化标志

// 搜索防抖定时器
let optionalSearchTimer: NodeJS.Timeout | null = null
let selectedSearchTimer: NodeJS.Timeout | null = null

// 初始化数据
const initializeData = () => {
  isInitializing.value = true

  optionalList.value = [...(props.optionalData || [])]
  selectedList.value = [...(props.selectedData || [])]

  // 从可选列表中移除已选的项
  optionalList.value = optionalList.value.filter(item =>
    !selectedList.value.some(selected => selected.id === item.id)
  )

  // 延迟重置初始化标志，确保watch不会在初始化期间触发
  setTimeout(() => {
    isInitializing.value = false
  }, 0)
}

// 清空所有数据
const clearAllData = () => {
  optionalList.value = []
  selectedList.value = []
  optionalSearch.value = ''
  selectedSearch.value = ''
  optionalCurrentPage.value = 1
  selectedCurrentPage.value = 1
  selectedOptional.value = []
  selectedSelected.value = []

  // 清理定时器
  if (optionalSearchTimer) {
    clearTimeout(optionalSearchTimer)
    optionalSearchTimer = null
  }
  if (selectedSearchTimer) {
    clearTimeout(selectedSearchTimer)
    selectedSearchTimer = null
  }

  // 重置loading状态
  optionalLoading.value = false
  optionalSearchLoading.value = false
  selectedSearchLoading.value = false
}

// 可选列表搜索过滤
const filteredOptionalList = computed(() => {
  if (!optionalSearch.value) return optionalList.value

  return optionalList.value.filter(item => {
    // 根据配置的列进行搜索
    return props.config.columns.some(column => {
      const value = item[column.prop]
      return value && value.toString().toLowerCase().includes(optionalSearch.value.toLowerCase())
    })
  })
})

// 已选列表搜索过滤
const filteredSelectedList = computed(() => {
  if (!selectedSearch.value) return selectedList.value

  return selectedList.value.filter(item => {
    // 根据配置的列进行搜索
    return props.config.columns.some(column => {
      const value = item[column.prop]
      return value && value.toString().toLowerCase().includes(selectedSearch.value.toLowerCase())
    })
  })
})

// 可选列表分页数据
const paginatedOptionalList = computed(() => {
  const start = (optionalCurrentPage.value - 1) * pageSize.value
  const end = start + pageSize.value
  return filteredOptionalList.value.slice(start, end)
})

// 已选列表分页数据
const paginatedSelectedList = computed(() => {
  const start = (selectedCurrentPage.value - 1) * pageSize.value
  const end = start + pageSize.value
  return filteredSelectedList.value.slice(start, end)
})

// 分页相关方法
const handleOptionalPageChange = (page: number) => {
  optionalCurrentPage.value = page
}

const handleSelectedPageChange = (page: number) => {
  selectedCurrentPage.value = page
}

// 多选事件
const handleOptionalSelectionChange = (val: SelectionItem[]) => {
  selectedOptional.value = val
}

const handleSelectedSelectionChange = (val: SelectionItem[]) => {
  selectedSelected.value = val
}

// 移动到已选
const moveToSelected = () => {
  selectedList.value.push(...selectedOptional.value)
  // 从可选列表中移除已选的项
  optionalList.value = optionalList.value.filter(item =>
    !selectedOptional.value.some(selected => selected.id === item.id)
  )
  selectedOptional.value = []
  // 重置分页
  optionalCurrentPage.value = 1
  selectedCurrentPage.value = 1
}

// 移动到可选
const moveToOptional = () => {
  optionalList.value.push(...selectedSelected.value)
  // 从已选列表中移除
  selectedList.value = selectedList.value.filter(item =>
    !selectedSelected.value.some(selected => selected.id === item.id)
  )
  selectedSelected.value = []
  // 重置分页
  optionalCurrentPage.value = 1
  selectedCurrentPage.value = 1
}

// 确定按钮事件
const handleConfirm = () => {
  console.log(selectedList.value, "selectedList.value");

  emit('confirm', selectedList.value)
}

// 取消按钮事件
const handleCancel = () => {
  emit('cancel')
}

// 监听已选列表变化，通知父组件（避免在初始化时触发）
watch(() => selectedList.value, (newValue) => {
  if (!isInitializing.value) {
    emit('selectedListChange', newValue)
  }
}, { deep: true })

// 监听可选区域搜索，添加防抖和loading效果
watch(() => optionalSearch.value, (newValue, oldValue) => {
  // 清除之前的定时器
  if (optionalSearchTimer) {
    clearTimeout(optionalSearchTimer)
  }

  // 如果有搜索内容且内容发生变化，显示loading
  if (newValue && newValue !== oldValue && newValue.trim() !== '') {
    optionalSearchLoading.value = true

    // 防抖处理
    optionalSearchTimer = setTimeout(() => {
      optionalSearchLoading.value = false
      // 重置分页到第一页
      optionalCurrentPage.value = 1
    }, 300)
  } else if (newValue === '' || newValue.trim() === '') {
    // 清空搜索时立即停止loading
    optionalSearchLoading.value = false
    optionalCurrentPage.value = 1
  }
})

// 监听已选区域搜索，添加防抖和loading效果
watch(() => selectedSearch.value, (newValue, oldValue) => {
  // 清除之前的定时器
  if (selectedSearchTimer) {
    clearTimeout(selectedSearchTimer)
  }

  // 如果有搜索内容且内容发生变化，显示loading
  if (newValue && newValue !== oldValue && newValue.trim() !== '') {
    selectedSearchLoading.value = true

    // 防抖处理
    selectedSearchTimer = setTimeout(() => {
      selectedSearchLoading.value = false
      // 重置分页到第一页
      selectedCurrentPage.value = 1
    }, 300)
  } else if (newValue === '' || newValue.trim() === '') {
    // 清空搜索时立即停止loading
    selectedSearchLoading.value = false
    selectedCurrentPage.value = 1
  }
})

// 监听弹窗关闭，清空所有数据
watch(() => props.modelValue, (newValue) => {
  if (!newValue) {
    // 弹窗关闭时清空所有数据
    clearAllData()
  }
})

// 监听props变化，初始化数据
watch(() => [props.optionalData, props.selectedData], () => {
  initializeData()
}, { immediate: true, deep: true })

// 设置可选区域loading状态的方法
const setOptionalLoading = (loading: boolean) => {
  optionalLoading.value = loading
}

// 组件销毁时清理定时器
onUnmounted(() => {
  if (optionalSearchTimer) {
    clearTimeout(optionalSearchTimer)
  }
  if (selectedSearchTimer) {
    clearTimeout(selectedSearchTimer)
  }
})

// 暴露方法给父组件
defineExpose({
  initializeData,
  clearAllData,
  setOptionalLoading
})
</script>

<style scoped lang="scss">
.operate-btns {
  .el-button {
    width: 24px !important;
    height: 24px !important;
    border-radius: 4px;
    margin: 0 !important;
    padding: 0 !important;
    min-width: 24px !important;

    /* 禁用状态样式 */
    &.is-disabled {
      background-color: rgba(242, 247, 253, 1) !important;
      border-color: rgba(242, 247, 253, 1) !important;
      color: #c0c4cc !important;
    }
  }

  :deep(.el-button:not(.is-link)) {
    min-width: 24px !important;
    width: 24px !important;
    height: 24px !important;
    padding: 0 !important;

    /* 禁用状态的深层样式 */
    &.is-disabled {
      background-color: rgba(242, 247, 253, 1) !important;
      border-color: rgba(242, 247, 253, 1) !important;
      color: #c0c4cc !important;
    }
  }
}
</style>
